package com.umessage.hotel.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.redisson.api.RAtomicLong;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.umessage.common.service.RedissonService;
import com.umessage.common.service.impl.BaseService;
import com.umessage.hotel.dao.BreakfastCouponMapper;
import com.umessage.hotel.dao.BreakfastRecordMapper;
import com.umessage.hotel.domain.BreakfastCoupon;
import com.umessage.hotel.domain.BreakfastRecord;
import com.umessage.hotel.domain.MemberInfo;
import com.umessage.hotel.domain.OrderBreakfast;
import com.umessage.hotel.service.BreakfastCouponService;
import com.umessage.hotel.service.MemberInfoService;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service("breakfastCouponService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class BreakfastCouponServiceImpl extends BaseService<BreakfastCoupon> implements BreakfastCouponService {

	@Autowired
	private BreakfastCouponMapper breakfastCouponMapper;
	@Autowired
	private BreakfastRecordMapper breakfastRecordMapper;
	@Autowired
	private RedissonService redissonService;
	@Autowired
	private MemberInfoService memberInfoService;

	@Override
	public void addCoupons(BreakfastCoupon coupon) {
		this.save(coupon);
	}

	@Override
	public List<BreakfastCoupon> findBreakfastCouponsToday(BreakfastCoupon coupon) {
		/*try {
			Example example = new Example(BreakfastCoupon.class);
			Criteria createCriteria = example.createCriteria();
			if (StringUtils.isNotBlank(coupon.getMemberId())) {
				createCriteria.andCondition("member_id=", coupon.getMemberId());
			}
			if (StringUtils.isNotBlank(coupon.getValidDate())) {
				createCriteria.andCondition("valid_date=", coupon.getValidDate());
			}

			if (StringUtils.isNotBlank(coupon.getUseStatus())) {
				createCriteria.andCondition("use_status=", coupon.getUseStatus());
			}
			example.setOrderByClause("use_status+0,type+0");

			return this.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<>();
		}*/
		return this.breakfastCouponMapper.findBreakfastCouponsToday(coupon);
	}

	@Override
	public List<BreakfastCoupon> findBreakfastCouponsAfter(BreakfastCoupon coupon) {
		try {
			Example example = new Example(BreakfastCoupon.class);
			Criteria createCriteria = example.createCriteria();
			if (StringUtils.isNotBlank(coupon.getMemberId())) {
				createCriteria.andCondition("member_id=", coupon.getMemberId());
			}
			if (StringUtils.isNotBlank(coupon.getValidDate())) {
				createCriteria.andCondition("DATE_FORMAT(valid_date, '%Y-%m-%d')>", coupon.getValidDate());
			}
			example.setOrderByClause("DATE_FORMAT(valid_date, '%Y-%m-%d'),use_status+0,type+0");
			return this.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}

	@Override
	public List<BreakfastCoupon> findBreakfastCouponsHistory(BreakfastCoupon coupon) {
		/*try {
			Example example = new Example(BreakfastCoupon.class);
			Criteria createCriteria = example.createCriteria();
			if (StringUtils.isNotBlank(coupon.getMemberId())) {
				createCriteria.andCondition("member_id=", coupon.getMemberId());
			}
			if (StringUtils.isNotBlank(coupon.getValidDate())) {
				createCriteria.andCondition("DATE_FORMAT(valid_date, '%Y-%m-%d')<", coupon.getValidDate());
			}
			example.setOrderByClause("DATE_FORMAT(valid_date, '%Y-%m-%d') desc,use_status+0,type+0");
			return this.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<>();
		}*/
		return this.breakfastCouponMapper.findBreakfastCouponsHistory(coupon);
	}

	@Override
	public Integer findBreakfastCouponsTodayCount(BreakfastCoupon coupon) {
		try {
			Example example = new Example(BreakfastCoupon.class);
			Criteria createCriteria = example.createCriteria();
			if (StringUtils.isNotBlank(coupon.getMemberId())) {
				createCriteria.andCondition("member_id=", coupon.getMemberId());
			}
			if (StringUtils.isNotBlank(coupon.getValidDate())) {
				createCriteria.andCondition("valid_date=", coupon.getValidDate());
			}
			createCriteria.andCondition("use_status=0");
			return this.breakfastCouponMapper.selectCountByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	@Override
	@Transactional
	public void useBreakfastCoupon(BreakfastRecord useRecord) {

		BreakfastCoupon coupon = new BreakfastCoupon();
		coupon.setMemberId(useRecord.getMemberId());
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		coupon.setValidDate(sdf.format(useRecord.getValidDate()));
		coupon.setUseStatus("0");
		try {
			
			MemberInfo member = memberInfoService.findMemberById(useRecord.getMemberId());

			if (member == null) {
				throw new RuntimeException("invalid member id :" + useRecord.getMemberId());
			}

			// 数据按照购买类型升序排列
			List<BreakfastCoupon> list = findBreakfastCouponsToday(coupon);

			if (useRecord.getAmount() <= 0) {
				throw new RuntimeException("coupon use_amount can not 0");
			}

			if (useRecord.getAmount() > list.size()) {
				throw new RuntimeException("coupon not enough");
			}

			// 生成流水号
			SimpleDateFormat df = new SimpleDateFormat("yyMMdd");
			String today = df.format(new Date());
			RAtomicLong atomicLong = redissonService.getRAtomicLong("bf_coupon_record_sn");
			//每一天重新计数
			if (!atomicLong.isExists()) {
				System.out.println("atomicLong not exists");
				
				Calendar cal = Calendar.getInstance();
				cal.set(Calendar.HOUR_OF_DAY, 0);
				cal.set(Calendar.SECOND, 0);
				cal.set(Calendar.MINUTE, 0);
				cal.set(Calendar.MILLISECOND, 001);
				cal.set(Calendar.DATE, cal.get(Calendar.DATE) + 1);
				
				atomicLong.set(1);
				//设置超时时间明天凌晨
				boolean success = atomicLong.expireAt(cal.getTime());
				if(!success) {
					System.out.println("atomicLong set expire error");
				}
			}
			String sn = String.format("%010d", atomicLong.incrementAndGet());
			String recordSn = today + sn;
			
			useRecord.setHotelId(member.getHotelId());
			useRecord.setRecordSn(recordSn);
			useRecord.setAddTime(new Date());
			useRecord.setMobile(member.getMobile());

			breakfastRecordMapper.saveBreakfastRecord(useRecord);
			List<BreakfastCoupon> sublist = list.subList(0, useRecord.getAmount());
			for (BreakfastCoupon bc : sublist) {
				bc.setRecordId(String.valueOf(useRecord.getId()));
				bc.setUseStatus("1");
				bc.setUseTime(new Date());
				this.updateNotNull(bc);
			}

		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}

	}

	@Override
	public List<BreakfastRecord> findRecords(String hotelId, Integer page, Integer rows,String mobile) {
		Map<String,String> map=new HashMap<>();
		map.put("hotelId", hotelId);
		map.put("mobile", mobile);
		PageHelper.startPage(page, rows,true,false,true); 
		List<BreakfastRecord> records = this.breakfastRecordMapper.findRecords(map);
		for (BreakfastRecord br : records) {
			String mobile1=br.getMobile();
			if(mobile1!=null) {
				char[] m =  mobile1.toCharArray();
               for(int i=0; i<m.length;i++){
                   if(i>2 && i<7){
                       m[i] = '*';
                   }
               }
               br.setMobile(String.valueOf(m));
            }
		}
		return records;
	}
	@Override
	public void addBrakefastCoupons(OrderBreakfast orderBKF) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date start = sdf.parse(orderBKF.getValidStart());//开始时间
			Date end=sdf.parse(orderBKF.getValidEnd());//结束时间
			int days = ((int)(end.getTime()/1000)-(int)(start.getTime()/1000))/3600/24 + 1;
			for (int i = 0; i < days; i++) {
				Calendar cale = Calendar.getInstance();
				cale.setTime(start);
				cale.add(Calendar.DAY_OF_MONTH, i);
				for (int j = 0; j < orderBKF.getNumDaily(); j++) {
					BreakfastCoupon coupon=new BreakfastCoupon();
					coupon.setMemberId(orderBKF.getMemberId());
					coupon.setBfOrderId(orderBKF.getBfOrderId()+"");
					coupon.setType("2");
					coupon.setUseStatus("0");
					coupon.setHotelId(orderBKF.getHotelId());
					coupon.setValidDate(sdf.format(cale.getTime()));
					coupon.setAddTime(new Date());
					this.addCoupons(coupon);
				}
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void addBrakefastCouponsPC(OrderBreakfast orderBKF) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date start = sdf.parse(orderBKF.getValidStart());//开始时间
			Date end=sdf.parse(orderBKF.getValidEnd());//结束时间
			int days = ((int)(end.getTime()/1000)-(int)(start.getTime()/1000))/3600/24 + 1;
			for (int i = 0; i < days; i++) {
				Calendar cale = Calendar.getInstance();
				cale.setTime(start);
				cale.add(Calendar.DAY_OF_MONTH, i);
				for (int j = 0; j < orderBKF.getNumDaily(); j++) {
					BreakfastCoupon coupon=new BreakfastCoupon();
					coupon.setMemberId(orderBKF.getMemberId());
					coupon.setBfOrderId(orderBKF.getBfOrderId()+"");
					coupon.setType("1");
					coupon.setHotelId(orderBKF.getHotelId());
					coupon.setUseStatus("0");
					coupon.setValidDate(sdf.format(cale.getTime()));
					coupon.setAddTime(new Date());
					this.addCoupons(coupon);
				}
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

	@Override
	public Integer countNumTodayByType(BreakfastCoupon coupon) {
		return this.breakfastCouponMapper.countNumTodayByType(coupon);
	}

	@Override
	public Integer countCheckToday(BreakfastCoupon coupon) {
		return this.breakfastCouponMapper.countCheckToday(coupon);
	}

	@Override
	public Integer countUseToday(BreakfastCoupon coupon) {
		// TODO Auto-generated method stub
		return this.breakfastCouponMapper.countUseToday(coupon);
	}
}
